unit PlayControl;

interface

uses
  SimpleThread,
  Windows, SysUtils, Classes;

type
  TPlayControl = class (TComponent)
  private
    FNeedSleepTight : integer;
    FPaused : boolean;
    FSimpleThread : TSimpleThread;
    procedure on_Repeat(Sender:TObject);
  private
    FOnWork: TNotifyEvent;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

    procedure Play;
    procedure Pause;

    procedure SleepTight;
    procedure WakeUp;
  published
    property OnWork : TNotifyEvent read FOnWork write FOnWork;
  end;

implementation

{ TPlayControl }

constructor TPlayControl.Create(AOwner: TComponent);
begin
  inherited;

  FPaused := true;
  FNeedSleepTight := 0;

  FSimpleThread := TSimpleThread.Create(on_Repeat);
  FSimpleThread.Name := 'PlayControl';
end;

destructor TPlayControl.Destroy;
begin
  FSimpleThread.Terminate;

  inherited;
end;

procedure TPlayControl.on_Repeat(Sender: TObject);
var
  iNeedSleepTight : integer;
begin
  while not FSimpleThread.Terminated do begin
    if FPaused then FSimpleThread.SleepTight;

    if Assigned(FOnWork) then FOnWork(Self);

    iNeedSleepTight := InterlockedExchange(FNeedSleepTight, 0);
    if iNeedSleepTight = 1 then FSimpleThread.SleepTight;
  end;
end;

procedure TPlayControl.Pause;
begin
  FPaused := true;
  SleepTight;
end;

procedure TPlayControl.Play;
begin
  FPaused := false;
  WakeUp;
end;

procedure TPlayControl.SleepTight;
begin
  FNeedSleepTight := 1;
end;

procedure TPlayControl.WakeUp;
begin
  if not FPaused then FSimpleThread.WakeUp;
end;

end.
